﻿using System;
using System.Collections;
using Huirui.Cavan.Domain.MainBoundedContext.PurchaseModule;
using Huirui.Cavan.Domain.MainBoundedContext.SearchModule;
using Huirui.Cavan.Application.MainBoundedContext.SystemModule;
using Huirui.Cavan.Domain.Seedwork;
using Spring.Context.Support;
using Huirui.Cavan.Domain.MainBoundedContext.SystemModule;
using Huirui.Cavan.Core.Extension;
using System.Collections.Generic;
using System.Linq;
using Huirui.Cavan.Domain.MainBoundedContext.ReportModule;
using Huirui.Cavan.Application.MainBoundedContext.StockModule;
using Huirui.Cavan.Domain.MainBoundedContext.StockModule;

namespace Huirui.Cavan.Application.MainBoundedContext.PurchaseModule
{
    #region PurchaseReturn

    public class PurchaseReturnAppService : BaseAppService<PurchaseReturn, string, PurchaseReturnSearch, IPurchaseReturnRepository>, IPurchaseReturnAppService
    {
        private IStockInOutAppService StockInAppService { get; set; }
        private IStockAppService StockAppService { get; set; }
        private IUnPayAppService UnPayAppService { get; set; }
        private IStockInOutTypeAppService StockInOutTypeAppService { get; set; }
        private IPurchaseAppService PurchaseAppService { get; set; }
        private IStockInOutDetailAppService StockInOutDetailAppService { get; set; }
        private ISupplierAppService SupplierAppService { get; set; }
        private IProjectAppService ProjectAppService { get; set; }
        private IWareHouseAppService WareHouseAppService { get; set; }

        private Employee _employee;
        private Purchaser _purchaser;

        public override BoolGenericResult<PurchaseReturn> AddOrUpdate(PurchaseReturn entity)
        {
            Init();
            AddPurchaseReturn result = new AddPurchaseReturn();
            this.StockAppService = this.SpringContext.GetObject(StockModuleConst.STOCKAPPSERVICE) as IStockAppService;
            this.StockInOutTypeAppService = this.SpringContext.GetObject(StockModuleConst.STOCKINOUTTYPEAPPSERVICE) as IStockInOutTypeAppService;
            this.PurchaseAppService = this.SpringContext.GetObject(PurchaseModuleConst.PURCHASEAPPSERVICE) as IPurchaseAppService;
            this.StockInOutDetailAppService = this.SpringContext.GetObject(StockModuleConst.STOCKINOUTDETAILAPPSERVICE) as IStockInOutDetailAppService;
            this.SupplierAppService = this.SpringContext.GetObject(SystemModuleConst.SUPPLIERAPPSERVICE) as ISupplierAppService;
            this.ProjectAppService = this.SpringContext.GetObject(SystemModuleConst.PROJECTAPPSERVICE) as IProjectAppService;
            this.WareHouseAppService = this.SpringContext.GetObject(StockModuleConst.WAREHOUSEAPPSERVICE) as IWareHouseAppService;
            this.UnPayAppService = this.SpringContext.GetObject(PurchaseModuleConst.UNPAYAPPSERVICE) as IUnPayAppService;

            _employee = this.EmployeeAppService.GetBySearch(SearchFactory.CreateEmployeeSearch(SecurityAppService.UserAccount.Id)).FirstOrDefault();
            _purchaser = new Purchaser(_employee);

            PurchaseReturn oldPurchaseReturn = null;
            UnPay oldUnPay = null;
            //加载数据
            if (entity.Id.IsNotEmpty())
            {
                oldPurchaseReturn = this.Repository.Get(entity.Id);
            }
            if (entity.Purchase.IsNotNull() && entity.Purchase.Id.IsNotEmpty())
            {
                entity.Purchase = this.PurchaseAppService.GetById(entity.Purchase.Id);
            }
            if (entity.WareHouse.IsNotNull() && entity.WareHouse.Id.IsNotEmpty())
            {
                entity.WareHouse = this.WareHouseAppService.GetById(entity.WareHouse.Id);
            }
            if (entity.Supplier.IsNotNull() && entity.Supplier.Id.IsNotEmpty())
            {
                entity.Supplier = this.SupplierAppService.GetById(entity.Supplier.Id);
            }
            if (entity.PurchaseEmployee.IsNotNull() && entity.PurchaseEmployee.Id.IsNotEmpty())
            {
                entity.PurchaseEmployee = this.EmployeeAppService.GetById(entity.PurchaseEmployee.Id);
            }
            if (entity.Project.IsNotNull() && entity.Project.Id.IsNotEmpty())
            {
                entity.Project = this.ProjectAppService.GetById(entity.Project.Id);
            }
            //获取所有有效库存
            List<StockInOutDetail> allStockInDetails = new List<StockInOutDetail>();
            foreach (StockInOutDetail siod in entity.StockInOut.StockInOutDetails)
            {
                IList<StockInOutDetail> tempStockInDetails = this.StockInOutDetailAppService.GetBySearch(SearchFactory.CreateStockInDetailSearch(siod.Stock.Id, true)).ToList();
                if (tempStockInDetails.IsNotNull())
                {
                    allStockInDetails.AddRange(tempStockInDetails);
                }
                siod.WareHouse = entity.WareHouse;
                siod.Stock = this.StockAppService.GetById(siod.Stock.Id);
                siod.Stock.StockByWareHouseReports = this.StockAppService.GetStocksByWareHouseReport(entity.WareHouse.Id, siod.Stock.Id);
            }

            StockInOutType stockInOutType = this.StockInOutTypeAppService.GetById(SystemIdentifier.DefaultStockInOutType.PurchaseReturn.GetHashCode());

            if (oldPurchaseReturn.IsNull())
            {      
                IIDGenerateAppService idGenerateAppService = this.SpringContext.GetObject(SystemModuleConst.IDGENERATEAPPSERVICE, new object[] { _employee.Corporation }) as IIDGenerateAppService;
                entity.Id = idGenerateAppService.GenerateID(SystemIdentifier.ReceiptCodeRuleType.PurchaseReturn);

                //采购退货
                result = _purchaser.ReturnOrderStock(entity.Id, allStockInDetails, entity.StockInOut, entity.ReturnDate, entity.SupplierInvoiceNumber, entity.Currency, entity.CurrencyRate, entity.TaxRate, entity.ReceivingNumber,
                    entity.InvoiceDescription, entity.Remark, entity.DeliveryAddress, entity.PurchaseEmployee, entity.Project, entity.Supplier, entity.WareHouse, entity.Contact,
                    entity.ContactTelephone, stockInOutType, entity.Purchase);
                if (result.IsSuccess)
                {
                    result.Object.StockInOut.Id = idGenerateAppService.GenerateID(SystemIdentifier.ReceiptCodeRuleType.StockOut);
                    this.UnPayAppService.Add(result.UnPay);
                    base.Add(result.Object);
                }
            }
            else
            {
                oldUnPay = this.UnPayAppService.GetSingleBySearch(SearchFactory.CreateUnPaySearch(PurchaseIdentifier.UnPayType.PurchaseReturn.GetHashCode(), oldPurchaseReturn.Id));
                result = _purchaser.UpdatePurchaeReturn(oldPurchaseReturn, oldUnPay, allStockInDetails, entity.ReturnDate, entity.SupplierInvoiceNumber, entity.Currency, entity.CurrencyRate, entity.ReceivingNumber,
                    entity.InvoiceDescription, entity.Remark, entity.DeliveryAddress, entity.PurchaseEmployee, entity.Project, entity.Supplier, entity.WareHouse,
                    entity.Contact, entity.ContactTelephone, entity.StockInOut);
                if (result.IsSuccess)
                {
                    this.UnPayAppService.Update(oldUnPay);
                    base.Update(result.Object);
                }     
            }
            if (result.IsSuccess)
            {
                foreach (StockInOutDetail siod in entity.StockInOut.StockInOutDetails)
                {
                    this.StockAppService.Update(siod.Stock);
                }
                foreach (StockInOutDetail siod in allStockInDetails)
                {
                    this.StockInOutDetailAppService.Update(siod);
                }
                result.Messages.Add("退货成功");
            }

            return result;
        }

        public IList<PurchaseReturnReport> GetPurchaseReturnReport(DateTime? startDate, DateTime? endDate, string purchaseReturnCode)
        {
            return this.Repository.GetPurchaseReturnReport(startDate, endDate, purchaseReturnCode);
        }

    }
    #endregion
}